'''
Módulo base de criação de partículas.

@author: hanniel
'''

from Metatools.Metatools import sgn
from math import sqrt

class Particle:

    def __init__(self, fluid,static,boundary,initial_position, initial_velocity, initial_temperature, initial_pressure):
        
        self.boundary=boundary 
        '''boundary = indica o patch a que a partícula pertence, se sim, ou não ('no').'''
        self.static=static
        '''static =  Mobilidade da partícula: Estática ('yes'), Móvel ('no')'''

        self.X=initial_position[0]
        self.Y=initial_position[1]
        '''self.Z=position[2]'''
        
        self.U=initial_velocity[0]
        self.V=initial_velocity[1]
        '''self.W=initial_velocity[2]''' 
        
        self.T=initial_temperature
        self.P=initial_pressure
        
        if fluid=='':
            
            ''' Trata-se de um patch com fluido genérico, e suas características físico-químicas não são importantes'''
            self.RHO=0.0
            self.MU=0.0
        else:
        
            self.fluid=fluid
            self.RHO=fluid.rho
            self.MU=fluid.mu
        
        self.STRESS=0
        
        self.r=0
        self.center_x=0
        self.center_y=0
        
    def handle_collisions(self, target_particle):
        
        '''Cheque as possíveis colisões da partícula'''
        
        if self.static == 'yes': # A checagem só é feita para partículas móveis
            
            pass
        
        else:
        
            Fx = abs((self.X+self.r)-target_particle.center_x)**2-target_particle.r**2
            Fy = abs((self.Y+self.r)-target_particle.center_y)**2-target_particle.r**2
            F=sqrt(Fx**2+Fy**2)
        
            #Se F>0, a partícula está fora da primitiva
            if F>0:  
            
                pass
            #Se F<=0, a partícula está na superfície ou no interior da primitiva
        
            elif F<=0:
        
                nx=sgn(Fx)*((target_particle.center_x-(self.X+self.r))/abs(target_particle.center_x-(self.X+self.r)))
                ny=sgn(Fy)*((target_particle.center_y-(self.Y+self.r))/abs(target_particle.center_y-(self.Y+self.r)))
        
                if target_particle.slip_conditions=='slip':
            
                    cr=1.0
            
                if target_particle.slip_conditions=='no_slip':
            
                    cr=0

        
                self.U=self.U-(1+cr)*(self.U*nx)*nx
                self.V=self.V-(1+cr)*(self.V*ny)*ny
        
                if target_particle.static=='no':

                    target_particle.U=target_particle.U-(1+cr)*(target_particle.U*nx)*nx
                    target_particle.V=target_particle.V-(1+cr)*(target_particle.V*ny)*ny
        
        
        